# coding: utf-8
from importlib import import_module
from pathlib import Path
from typing import Union, Dict

from PySide6.QtCore import QObject, Signal
from loguru import logger

from .api_base import APIBase
from ..settings import PLUGINS_DIR


class PluginManager(QObject):
    """
    插件管理器
    """
    registerSignal = Signal(object)  # 插件注册信号
    unregisterSignal = Signal(object)  # 插件注销信号

    def __init__(self):
        super().__init__()
        self.plugins = {}  # type: Dict[str, APIBase]

    def __getitem__(self, item):
        return self.plugins[item]

    def __setitem__(self, key, value):
        self.plugins[key] = value

    def __delitem__(self, key):
        del self.plugins[key]

    def __contains__(self, item):
        return item in self.plugins

    def __len__(self):
        return len(self.plugins)

    def values(self):
        return list(self.plugins.values())

    def keys(self):
        return list(self.plugins.keys())

    def get(self, key, default=None):
        return self.plugins.get(key, default)

    def register(self, file: Union[str, Path]):
        logger.info(f'注册插件: {file}')
        if isinstance(file, str):
            file = Path(file)
        if not file.exists():
            logger.error(f'插件文件 {file} 不存在')
            return
        stem = file.stem
        if stem in self.plugins:
            logger.warning(f'插件 {stem} 已存在')
            return
        try:
            module = import_module(f'plugins.{stem}')
            if not hasattr(module, 'Plugin'):
                logger.error(f'插件文件 {stem} 缺少 Plugin 类')
                return
            plugin = module.Plugin  # type: APIBase
            logger.info('%s, %s' % (plugin, plugin.name))
            self.plugins[plugin.name] = plugin
            plugin.local_file = file
            self.registerSignal.emit(plugin)
            logger.info(self.plugins)
            logger.info(f'注册插件成功: {stem}, {plugin.name}')
        except Exception as e:
            logger.error(f'注册插件失败: {stem}, {e}')

    def unregister(self, key: str):
        if key not in self.plugins:
            logger.warning(f'插件 {key} 不存在')
            return
        plugin = self.plugins.pop(key)
        self.unregisterSignal.emit(plugin)
        logger.info(f'注销插件成功: {key}, {plugin.name}')
        del plugin

    def reload(self, key: str):
        if key not in self.plugins:
            logger.warning(f'插件 {key} 不存在')
            return

    def clear(self):
        for key in self.plugins.keys():
            self.unregister(key)
        self.plugins.clear()

    def loadAll(self):
        for file in PLUGINS_DIR.glob('*.py'):
            if file.stem.startswith('_'):
                continue
            self.register(file)
        logger.info(self.plugins)


pluginManager = PluginManager()
